package custApi

import (
	"encoding/json"
	"fmt"
	"github.com/labstack/echo/v5"
	"github.com/mozillazg/go-pinyin"
	"io"
	"net/http"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/pocketbase/pocketbase"
	"github.com/pocketbase/pocketbase/apis"
	"github.com/pocketbase/pocketbase/core"
	"github.com/pocketbase/pocketbase/tools/search"
)

func LoadCustomizeRouter(app *pocketbase.PocketBase) {
	HelloExample(app)
	RouteStatsApi(app)
	NovelGroupByLetterApi(app)
	SearchCombinedApi(app)
}

func HelloExample(app *pocketbase.PocketBase) {
	app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
		// 定义自定义的 `GET /api/custom/hello` 路由
		e.Router.GET("/api/custom/hello", func(c echo.Context) error {
			return c.JSON(http.StatusOK, map[string]string{
				"message": "Hello, PocketBase!",
			})
		})
		return nil
	})
}

func RouteStatsApi(app *pocketbase.PocketBase) {
	app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
		// 定义获取路由访问统计的API
		e.Router.GET("/api/custom/route-stats", func(c echo.Context) error {
			routePath := c.QueryParam("route")
			if routePath == "" {
				return apis.NewBadRequestError("Missing route parameter", nil)
			}
			fieldResolver := search.NewSimpleFieldResolver([]string{
				"rowid", "id", "created", "updated",
				"level", "message", "data",
				`^data\.[\w\.\:]*\w+$`,
			}...)

			filter := fmt.Sprintf("data.url='%s'", routePath)
			expr, err := search.FilterData(filter).BuildExpr(fieldResolver)
			if err != nil {
				return apis.NewBadRequestError("Invalid filter format.", err)
			}

			stats, err := app.LogsDao().LogsStats(expr)
			if err != nil {
				return apis.NewBadRequestError("Failed to generate route stats.", err)
			}

			// Calculate total visits
			total := 0
			for _, stat := range stats {
				total += stat.Total
			}

			response := map[string]interface{}{
				"route":     routePath,
				"total":     total,
				"timestamp": time.Now().Format("2006-01-02"),
				"details":   stats,
			}

			return c.JSON(http.StatusOK, response)
		})
		return nil
	})
}

func NovelGroupByLetterApi(app *pocketbase.PocketBase) {
	app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
		e.Router.GET("/api/custom/novels-by-letter", func(c echo.Context) error {
			// 调用原始API获取小说数据
			url := "http://xiaoerduo.alinaduan.com:8090/api/collections/55d1kxc69hkyzjz/records?page=1&perPage=10000&sort=-created&filter=is_show=true"
			resp, err := http.Get(url)
			if err != nil {
				return apis.NewApiError(500, "Failed to fetch novels", err)
			}
			defer resp.Body.Close()

			body, err := io.ReadAll(resp.Body)
			if err != nil {
				return apis.NewApiError(500, "Failed to read response", err)
			}

			// 解析原始数据
			var novelResp struct {
				Items []struct {
					CollectionId   string   `json:"collectionId"`
					CollectionName string   `json:"collectionName"`
					Created        string   `json:"created"`
					Id             string   `json:"id"`
					IsShow         bool     `json:"is_show"`
					NovelTags      []string `json:"novel_tags"`
					Pwd            string   `json:"pwd"`
					ResourceUrl    string   `json:"resource_url"`
					Description    string   `json:"description"`
					Title          string   `json:"title"`
					Updated        string   `json:"updated"`
				} `json:"items"`
			}
			if err := json.Unmarshal(body, &novelResp); err != nil {
				return apis.NewApiError(500, "Failed to parse response", err)
			}

			// 定义返回的数据结构
			type NovelItem struct {
				CollectionId   string   `json:"collectionId"`
				CollectionName string   `json:"collectionName"`
				Created        string   `json:"created"`
				Id             string   `json:"id"`
				IsShow         bool     `json:"is_show"`
				NovelTags      []string `json:"novel_tags"`
				Pwd            string   `json:"pwd"`
				ResourceUrl    string   `json:"resource_url"`
				Description    string   `json:"description"`
				Title          string   `json:"title"`
				Updated        string   `json:"updated"`
			}

			type LetterGroup struct {
				Letter string      `json:"letter"`
				Count  int         `json:"count"`
				Novels []NovelItem `json:"novels"`
			}

			type ResponseData struct {
				TotalNovels int           `json:"totalNovels"`
				Groups      []LetterGroup `json:"groups"`
				Letters     []string      `json:"letters"` // 用于快速导航
			}

			// 按首字母分组
			groupedNovels := make(map[string][]NovelItem)
			totalNovels := 0

			for _, item := range novelResp.Items {
				if title := strings.TrimSpace(item.Title); title != "" {
					firstLetter := strings.ToUpper(string([]rune(title)[0]))
					firstLetter = getFirstLetter(firstLetter)
					groupedNovels[firstLetter] = append(groupedNovels[firstLetter], NovelItem{
						CollectionId:   item.CollectionId,
						CollectionName: item.CollectionName,
						Created:        item.Created,
						Id:             item.Id,
						IsShow:         item.IsShow,
						NovelTags:      item.NovelTags,
						Pwd:            item.Pwd,
						ResourceUrl:    item.ResourceUrl,
						Description:    item.Description,
						Title:          item.Title,
						Updated:        item.Updated,
					})
					totalNovels++
				}
			}

			// 构建有序的返回数据
			letters := make([]string, 0, len(groupedNovels))
			for letter := range groupedNovels {
				letters = append(letters, letter)
			}
			// 字母排序
			sort.Strings(letters)

			// 构建最终分组数据
			groups := make([]LetterGroup, 0, len(letters))
			for _, letter := range letters {
				novels := groupedNovels[letter]
				if len(novels) > 0 {
					groups = append(groups, LetterGroup{
						Letter: letter,
						Count:  len(novels),
						Novels: novels,
					})
				}
			}

			// 构建最终响应
			response := ResponseData{
				TotalNovels: totalNovels,
				Groups:      groups,
				Letters:     letters,
			}

			return c.JSON(http.StatusOK, response)
		})
		return nil
	})
}

func SearchCombinedApi(app *pocketbase.PocketBase) {
	app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
		e.Router.GET("/api/custom/search", func(c echo.Context) error {
			keyword := c.QueryParam("keyword")
			baseURL := "http://xiaoerduo.alinaduan.com:8090/api"

			// 先检查关键词是否为标签
			var tagID string
			if keyword != "" {
				tagURL := fmt.Sprintf("%s/collections/y8aeywt085e24q3/records?page=1&perPage=40&sort=-created&filter=name='%s'", baseURL, keyword)
				resp, err := http.Get(tagURL)
				if err != nil {
					return apis.NewApiError(500, "Failed to fetch tags", err)
				}
				defer resp.Body.Close()

				var tagResp struct {
					Items []struct {
						ID   string `json:"id"`
						Name string `json:"name"`
					} `json:"items"`
				}
				if err := json.NewDecoder(resp.Body).Decode(&tagResp); err != nil {
					return apis.NewApiError(500, "Failed to parse tag response", err)
				}

				// 如果找到匹配的标签，记录标签ID
				if len(tagResp.Items) > 0 {
					tagID = tagResp.Items[0].ID
				}
			}

			// 构建两个 API 的 URL
			novelURL := fmt.Sprintf("%s/collections/55d1kxc69hkyzjz/records?page=1&perPage=10000&sort=-created", baseURL)
			audioURL := fmt.Sprintf("%s/collections/s6d85ek90cniwkg/records?page=1&perPage=10000&sort=-created", baseURL)

			// 构建过滤条件
			if keyword != "" {
				var novelFilter, audioFilter string
				if tagID != "" {
					// 如果是标签搜索，使用标签过滤
					novelFilter = fmt.Sprintf("novel_tags.name?='%s'&&is_show=true", keyword)
					audioFilter = fmt.Sprintf("audio_dramas_tags.name?='%s'&&is_show=true", keyword)
				} else {
					// 如果是普通关键词搜索，使用标题过滤
					novelFilter = fmt.Sprintf("title~'%s'&&is_show=true", keyword)
					audioFilter = fmt.Sprintf("title~'%s'&&is_show=true", keyword)
				}
				novelURL += "&filter=" + novelFilter
				audioURL += "&filter=" + audioFilter
			} else {
				novelURL += "&filter=is_show=true"
				audioURL += "&filter=is_show=true"
			}

			// 定义通用的响应结构
			type CommonResponse struct {
				TotalItems int         `json:"totalItems"`
				Items      interface{} `json:"items"`
			}

			// 定义等待组
			var wg sync.WaitGroup
			wg.Add(2)

			// 定义用于存储结果的变量
			var (
				novelResp CommonResponse
				audioResp CommonResponse
				fetchErr  error
			)

			// 获取小说数据
			go func() {
				defer wg.Done()
				resp, err := http.Get(novelURL)
				if err != nil {
					fetchErr = err
					return
				}
				defer resp.Body.Close()

				if err := json.NewDecoder(resp.Body).Decode(&novelResp); err != nil {
					fetchErr = err
					return
				}
			}()

			// 获取音频剧数据
			go func() {
				defer wg.Done()
				resp, err := http.Get(audioURL)
				if err != nil {
					fetchErr = err
					return
				}
				defer resp.Body.Close()

				if err := json.NewDecoder(resp.Body).Decode(&audioResp); err != nil {
					fetchErr = err
					return
				}
			}()

			// 等待所有 goroutine 完成
			wg.Wait()

			// 检查是否有错误发生
			if fetchErr != nil {
				return apis.NewApiError(500, "Failed to fetch data", fetchErr)
			}

			// 合并数据
			novelItems := novelResp.Items.([]interface{})
			audioItems := audioResp.Items.([]interface{})
			allItems := append(novelItems, audioItems...)

			// 按 created 字段排序
			sort.Slice(allItems, func(i, j int) bool {
				iCreated := allItems[i].(map[string]interface{})["created"].(string)
				jCreated := allItems[j].(map[string]interface{})["created"].(string)
				return iCreated > jCreated // 降序排序
			})

			// 构建合并后的响应
			response := CommonResponse{
				TotalItems: novelResp.TotalItems + audioResp.TotalItems,
				Items:      allItems,
			}

			return c.JSON(http.StatusOK, response)
		})
		return nil
	})
}

// 获取字符串的首字母（支持中文转拼音）
func getFirstLetter(s string) string {
	if s == "" {
		return ""
	}

	// 如果是ASCII字符，直接返回大写
	firstRune := []rune(s)[0]
	if firstRune < 128 {
		return strings.ToUpper(string(firstRune))
	}

	// 如果是中文，转换为拼音
	args := pinyin.NewArgs()
	args.Style = pinyin.FirstLetter // 只获取拼音首字母
	pys := pinyin.Pinyin(string(firstRune), args)
	if len(pys) > 0 && len(pys[0]) > 0 {
		return strings.ToUpper(pys[0][0])
	}

	return "Other" // 对于无法转换的字符返回 Other
}
